package com.mk.cloud.common.util.pay;

import com.mk.cloud.common.domain.PCoconfig;
import com.mk.cloud.common.enums.GlobalValues;
import com.mk.cloud.common.exception.UserException;
import org.osgl.util.S;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by liuys on 2016/12/12.
 */
public abstract class PayUtils {
    public PayUtils(){

    }
    public PayUtils(String path){

    }

    public static PayUtils payFactory(String payType, PCoconfig coconfig) {
        if (S.isEmpty(payType)) {
            throw new UserException("该订单没有支付类型");
        }
        PayUtils payUtils = null;
        switch (payType) {
//            case "0":
//                obj = WeixinPayUtils.class;
//                break;
//            case "WEIXIN":
//                obj = WeixinPayUtils.class;
//                break;
            case "2":
                payUtils = new AppAliPayUtils(coconfig);
                break;
            case "AppAliPay":
                payUtils = new AppAliPayUtils(coconfig);
                break;
//            case "3":
//                obj = YijiPay.class;
//                break;
//            case "YIJIFU":
//                obj = YijiPay.class;
//                break;
//            case "4":
//                obj = WeixinPayGzhUtils.class;
//                break;
//            case "WEIXINGZH":
//                obj = WeixinPayGzhUtils.class;
//                break;
            default:
                break;
        }
//        return obj;
        return payUtils;
    }

    public static Class payFactory(String payType) {
//        Class obj = null;
//        if (S.isEmpty(payType)) {
//            throw new UserException("该订单没有支付");
//        }
//        switch (payType) {
//            case "0":
//                obj = WeixinPayUtils.class;
//                break;
//            case "WEIXIN":
//                obj = WeixinPayUtils.class;
//                break;
//            case "2":
//                obj = AppAliPayUtils.class;
//                break;
//            case "AppAliPay":
//                obj = AppAliPayUtils.class;
//                break;
//            case "3":
//                obj = YijiPay.class;
//                break;
//            case "YIJIFU":
//                obj = YijiPay.class;
//                break;
//            case "4":
//                obj = WeixinPayGzhUtils.class;
//                break;
//            case "WEIXINGZH":
//                obj = WeixinPayGzhUtils.class;
//                break;
//            default:
//                break;
//        }
//        return obj;
        return AppAliPayUtils.class;
    }

    public static String getPayType(String payType) {
        String obj = "0";
        if (payType == null) {
            return "0";
        }
        switch (payType) {
            case "0":
                obj = "0";
                break;
            case "WEIXIN":
                obj = "0";
                break;

            case "2":
                obj = "2";
                break;
            case "YIJIFU":
                obj = "2";
                break;
            default:
                obj = "0";
                break;
        }
        return obj;
    }

    public static String getPayidDesc(String payType) {
        String obj = "0";
//        if (payType == null) {
//            return GlobalValues.ORDERPAYTYPE_1.value();
//        }
//        switch (payType) {
//            case "0":
//                obj = GlobalValues.ORDERPAYTYPE_1.value();
//                break;
//            case "WEIXIN":
//                obj = GlobalValues.ORDERPAYTYPE_1.value();
//                break;
//            case "1":
//                obj = GlobalValues.ORDERPAYTYPE_2.value();
//                break;
//            case "UNION":
//                obj = GlobalValues.ORDERPAYTYPE_2.value();
//                break;
//            case "2":
//                obj = GlobalValues.ORDERPAYTYPE_3.value();
//                break;
//            case "YIJIFU":
//                obj = GlobalValues.ORDERPAYTYPE_3.value();
//                break;
//            default:
//                obj = GlobalValues.ORDERPAYTYPE_1.value();
//                break;
//        }
        return obj;
    }

    public static Map<String, String> getMapFromXML(String xmlString) throws ParserConfigurationException, IOException, SAXException {

        //这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputStream is = new ByteArrayInputStream(xmlString.getBytes());
        Document document = builder.parse(is);

        //获取到document里面的全部结点
        NodeList allNodes = document.getFirstChild().getChildNodes();
        Node node;
        Map<String, String> map = new HashMap<String, String>();
        int i = 0;
        while (i < allNodes.getLength()) {
            node = allNodes.item(i);
            if (node instanceof Element) {
                map.put(node.getNodeName(), node.getTextContent());
            }
            i++;
        }
        return map;

    }

    public static Map<String, String> getMapFromBr(BufferedReader reader) throws Exception {
        String line = "";
        String xmlString = null;
        StringBuffer inputString = new StringBuffer();

        while ((line = reader.readLine()) != null) {
            inputString.append(line);
        }
        xmlString = inputString.toString();

        Map<String, String> map = PayUtils.getMapFromXML(xmlString);
        return map;
    }

    /**
     * 获取支付对象
     *
     * @param paramMap 支付参数（body,out_trade_no,total_fee,ipAddress,userid,username）
     * @return
     */
    public abstract Map<String, String> getPayObject(Map<String, String> paramMap);


    /**
     * 获取二维码支付链接
     *
     * @param paramMap 支付参数（body,out_trade_no,total_fee,ipAddress,userid,username）
     * @return
     */
    public abstract String getPayCodeUrl(Map<String, String> paramMap);

    /**
     * 获取支付信息
     *
     * @param payid 支付id
     */
    public abstract Map<String, String> getOrderInfo(String payid);

    /**
     * 关闭支付订单
     *
     * @param payid 支付id
     */
    public abstract boolean closeOrder(String payid);

    /**
     * 验证支付状态
     *
     * @param payid 支付id
     */
    public abstract Map<String, String> validatePayidState(String payid);

    /**
     * 支付单退款
     *
     * @param map 退款对象（payid:支付ID,aofid:退款ID,total_fee:支付金额,refund_fee:退款金额,userid:操作人ID）
     */
    public abstract boolean refundOrder(Map<String, String> map);

    /**
     * 获取签名信息
     *
     * @param map     签名参数
     * @param strType 返回类型（xml,sign,query）
     */
    public abstract String getSign(Map<String, String> map, String strType);

    public abstract String getSignown(Map<String, Object> map, String strType);

    /**
     * 转帐
     *
     * @param map 付款参数
     * @return 返回（成功或失败）
     */
    public abstract String transfer(Map<String, Object> map);

    /**
     * 查询企业余额转帐
     *
     * @param map 查询参数
     * @return 返回（map）
     */
    public abstract Map<String, Object> selTransfer(Map<String, Object> map);

    /**
     * 跳转钱包页
     */
    public abstract String goWallet(Map<String, Object> map);


    public abstract Map<String, Object> payCallback(Map<String, String> map);

    /**
     * 微信公众号支付，获取支付对象
     */
    public abstract Map<String, String> getPayObjectGzh(Map<String, String> paramMap);

    /**
     * 获取h5支付对象
     *
     * @param paramMap 支付参数（body,out_trade_no,total_fee,ipAddress,userid,username）
     * @return
     */
    public abstract Map<String, String> getPayObjecth5(Map<String, String> paramMap);

}
